Passed
Branchmaster (6dd67e)
by Plamen
02:53
created

table.js ➔ ... ➔ this.GoPage   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 20
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 4
eloc 17
c 2
b 1
f 0
nc 4
nop 1
dl 0
loc 20
rs 9.55
1
var strAsc = String.fromCharCode(9650); //▲
2
var strDesc = String.fromCharCode(9660);//▼
3
var xmlhttp; var d;
4
5
var table = new function(){
6
    this.rq = null;
7
    this.tail = [];
8
9
    this.ReloadData = function(tableId){
10
        var request = {};
11
        this.BuildRequest(request,tableId);
12
        this.LoadData(tableId,request);
13
    };
14
15
    this.BuildRequest = function(request, crntTableId, skipPropertyArray){
16
        this.rq = request;
17
        this.checkSkip = function(skipProperty){
18
            var result = false;
19
            if(skipPropertyArray && Object.prototype
20
                .toString.call(skipPropertyArray) === '[object Array]'){
21
                if(skipPropertyArray.indexOf(skipProperty)>=0){
22
                    result = true;
23
                }
24
            }
25
            return result;
26
        };
27
        this.getSort = function(){
28
            var table = document.getElementById(crntTableId);
29
            var thTags = table.getElementsByTagName("thead")[0]
30
                        .getElementsByTagName("th");
31
            for(var i = 0; i < thTags.length; i++ ){
32
                if(thTags[i].getElementsByTagName("a")[0] && thTags[i]
33
                    .getElementsByTagName("a")[0].getElementsByTagName("span")
34
                    .length === 1
35
                ){
36
                    var order = thTags[i].getElementsByTagName("a")[0]
37
                                .getElementsByTagName("span")[0].innerHTML;
38
                    if(order.length === 1){
39
                        this.rq.colNo = i;
40
                        this.rq.colOrd = (order === window.strDesc) ?
41
                                            "desc" : "asc";
42
                    }
43
                }
44
            }
45
        };
46
        this.getFilter = function(){
47
            var r = this.getFilterFieldsByTbaleID(crntTableId);
48
            if(r.filter !== null){
49
                this.rq.filter = r.filter;
50
            }
51
            if(r.filterBy !== null){
52
                this.rq.filterBy = r.filterBy;
53
            }
54
        };
55
56
        /* Build request object */
57
        if(!this.checkSkip("sort")){            this.getSort();         }
58
        if(!this.checkSkip("filter")){          this.getFilter();       }
59
60
        this.rq.tableId = crntTableId;
61
        return this.rq;
62
    };
63
64
    this.RequestToUrl = function(rq){
65
        var url=location.pathname + ".json" + location.search;
66
        if(typeof rq === "object"){
67
            var getUrlVarName = {
68
                colNo: "col", colOrd: "ord", filter: "filter", 
69
                filterBy: "filter-by", pageNo: "pg", exportType: "export",
70
                tableId: "table-id"
71
            };
72
            var flagFirst = location.search.length < 1 ? true : false;
73
            for(var r in rq){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
74
                var clue = flagFirst===true ? "?" : "&";
75
                url += clue + getUrlVarName[r] + "=" + rq[r];
76
                flagFirst = false;
77
            }
78
        }
79
        return url;
80
    };
81
82
    this.Filter = function(field){
83
        var request = {};
84
        var isSelect = field.tagName.toLowerCase() === "select";
85
        if(isSelect){
86
            var f = field.parentNode.parentNode.getElementsByTagName("input")[0];
87
            if('' === f.value){
88
                return;
89
            }
90
        }
91
        var crntTableId = isSelect ?
92
                            f.getAttribute("data-table-id") :
0 ignored issues
show
Bug introduced by
The variable f does not seem to be initialized in case isSelect on line 85 is false. Are you sure this can never be the case?
Loading history...
93
                            field.getAttribute("data-table-id");
94
        var exRq = this.rq;
95
        this.BuildRequest(request,crntTableId);
96
        if(exRq===null){
97
            this.LoadData(crntTableId,request);
98
        } else if(  request.filter !== exRq.filter ||
99
                    request.filterBy !== exRq.filterBy
100
        ){
101
            this.LoadData(crntTableId,request);
102
        }
103
    };
104
105
    this.GoPage = function(lnk){
106
        var request = {};
107
        var table = this.getParent(lnk,"table");
108
        var crntTableId = table.getAttribute("id");
109
        this.BuildRequest(request,crntTableId);
110
        //check & serve pagination jump links
111
        var jumpDir=lnk.innerHTML.trim().substr(0,1);
112
        if(jumpDir==="+" || jumpDir==="-"){
113
            var current = table.querySelector("tfoot .paging .a").innerHTML;
114
            var jump = lnk.innerHTML.replace("K","000").replace("M","000000000");
115
            var jumpPage = (parseInt(current)+parseInt(jump));
116
            lnk.parentNode.setAttribute("data-page",jumpPage);
117
            lnk.style.transform="none";
118
        }
119
        request.pageNo = lnk.parentNode.hasAttribute("data-page") ?
120
                         lnk.parentNode.getAttribute("data-page") :
121
                         lnk.innerHTML;
122
        this.LoadData(crntTableId,request);
123
        return false;
124
    };
125
126
    this.Export = function(lnk,eType){
127
        var request = {};
128
        var crntTableId = this.getParent(lnk,"table").getAttribute("id");
129
        this.BuildRequest(request,crntTableId);
130
        request.exportType = ["CSV","Excel"].indexOf(eType)>=0 ? eType : "csv";
131
        window.open(this.RequestToUrl(request));
132
        return false;
133
    };
134
135
    this.Sort = function(colNo,lnk){
136
        var request = {};
137
        var crntTableId = this.getParent(lnk,"table").getAttribute("id");
138
        this.BuildRequest(request,crntTableId);
139
        if(Math.round(colNo) === request.colNo){
140
            request.colOrd = request.colOrd === "asc" ? "desc" : "asc";
141
        } else {
142
            request.colNo=Math.round(colNo);
143
            request.colOrd = "asc";
144
        }
145
        this.LoadData(crntTableId,request);
146
        /* Clear and add new sort arrow */
147
        var headSpans = this.getParent(lnk,"thead").getElementsByTagName("span");
148
        for(var i=0; i < headSpans.length; i++){
149
            headSpans[i].innerHTML = "";
150
        }
151
        lnk.getElementsByTagName("span")[0].innerHTML = (request.colOrd === "desc" ? window.strDesc : window.strAsc);
152
    };
153
154
    this.DrawSection = function(tableContainer, dt, tSection){
155
        var section = tSection === "tfoot" ? "tfoot" : "tbody";
156
        tSection =  document.getElementById(tableContainer).
157
                        getElementsByTagName(section)[0];
158
        this.clearSection(tSection);
159
        for(var i=0; i < dt.length; i++) {
160
            var row = dt[i];
161
            var tRow = document.createElement("tr");
162
163
            this.DrawRow(row, tRow);
164
165
            tSection.appendChild(tRow);
166
            if(section === "tfoot"){
167
                this.footerProcessPaginationLinks(tSection);
168
            }
169
            this.AppendRowCalback(tableContainer);
170
        }
171
    };
172
173
    this.DrawRow = function(row, tRow){
174
        for(var cell in row){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
175
            var tCell = document.createElement("td");
176
            if(typeof row[cell] === "string" || typeof row[cell] === "number"){
177
                tCell.innerHTML = row[cell];
178
            } else if(typeof row[cell] === "object"){
179
                this.DrawCellFromObject(row, cell, tCell);
180
            }
181
            tRow.appendChild(tCell);
182
        }
183
    };
184
185
    this.DrawCellFromObject = function(row, cell, tCell){
186
        for(var attr in row[cell]){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
187
            if(typeof row[cell][attr] === "string"){
188
                tCell.innerHTML = row[cell][attr];
189
            } else if(typeof row[cell][attr] === "object"){
190
                for(var v in row[cell][attr]){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
191
                    tCell.setAttribute(v,row[cell][attr][v]);
192
                }
193
            }
194
        }
195
    };
196
197
    this.footerProcessPaginationLinks = function(tSection){
198
        var pLinks = tSection.querySelectorAll(".paging a");
199
        if(pLinks.length>0){
200
            for(var j=0; j < pLinks.length; j++){
201
                pLinks[j].setAttribute("href","javascript:void(0);");
202
                pLinks[j].setAttribute("onclick","return table.GoPage(this);");
203
            }
204
        }
205
    };
206
207
    this.clearSection = function(tSection){
208
        if(this.iePrior(9)){
209
            if(tSection.firstChild){
210
                while (tSection.firstChild) {
211
                    tSection.removeChild(tSection.firstChild);
212
                }
213
            }
214
        } else {
215
            tSection.innerHTML="";
216
        }
217
    };
218
219
    this.SetTheTableColumnsHoverEffect = function (tableContainer){
220
        if(this.iePrior(9)) {return;}
221
        var tContainer = document.getElementById(tableContainer);
222
        var tHcells = tContainer.rows[0].cells;
223
        for(var i=0; i < tHcells.length; i++){
224
            if(tHcells[i].firstChild.tagName === "A"){
225
                tHcells[i].firstChild.setAttribute("onmouseover","table.ColumnHover('"+tableContainer+"',"+i+");");
226
                tHcells[i].firstChild.setAttribute("onmouseout","table.ColumnHover('"+tableContainer+"');");
227
            }
228
        }
229
        var pLinks = tContainer.querySelectorAll("tfoot .paging a");
230
        if(pLinks.length>0){
231
            for(var j=0; j < pLinks.length; j++){
232
                pLinks[j].setAttribute("href","javascript:void(0);");
233
                pLinks[j].setAttribute("onclick","return table.GoPage(this);");
234
            }
235
        }
236
    };
237
238
    this.ColumnHover = function(tableContainer,index){
239
        if(this.iePrior(9)) {return;}
240
        var tRow = document.getElementById(tableContainer).rows;
241
        index = Math.round(index);
242
        for(var i=0; i < (tRow.length-1); i++){
243
            if(index >= 0){
244
                tRow[i].cells[index].setAttribute("lang","col-hover");
245
            } else {
246
                for(var j=0; j < tRow[i].cells.length; j++){
247
                    if(tRow[i].cells[j].lang){
248
                        tRow[i].cells[j].removeAttribute("lang");
249
                    }
250
                }
251
            }
252
        }
253
    };
254
255
    this.getFilterFieldsByTbaleID = function(tableID){
256
        var fields = {filterBy:null, filter:null};
257
        var filterDiv = this.getFilterDivByTableIDOrNull(tableID);
258
        if(filterDiv!==null) {
259
            var selectObj = filterDiv.getElementsByTagName("select")[0];
260
            var textObj = filterDiv.getElementsByTagName("input")[0];
261
            fields.filterBy = (selectObj===null || selectObj.options[selectObj.selectedIndex].value==="all") ? null : selectObj.options[selectObj.selectedIndex].value;
262
            fields.filter = (textObj===null || textObj.value.length === 0) ? null : encodeURIComponent(textObj.value.trim());
263
        }
264
        return fields;
265
    };
266
267
    this.getFilterDivByTableIDOrNull = function(tableID){
268
        var res = null;
269
        if(document.getElementById(tableID).parentNode.getElementsByTagName("div").length > 0){
270
            for (var i = 0; i < document.getElementById(tableID).parentNode.getElementsByTagName("div").length; i++) {
271
                if(document.getElementById(tableID).parentNode.getElementsByTagName("div")[i].getAttribute("class")==="filter"){
272
                    return document.getElementById(tableID).parentNode.getElementsByTagName("div")[i];
273
                }
274
            }
275
276
        }
277
        return res;
278
    };
279
280
    this.LoadData = function(tableContainer,rq){
281
        this.setVisability(tableContainer, false);
282
        if (window.XMLHttpRequest) { xmlhttp=new XMLHttpRequest(); /* code for IE7+, Firefox, Chrome, Opera, Safari */
283
        } else {  xmlhttp=new /** global: ActiveXObject */ActiveXObject("Microsoft.XMLHTTP"); /* code for IE6, IE5 */}
0 ignored issues
show
Bug introduced by
The variable ActiveXObject seems to be never declared. If this is a global, consider adding a /** global: ActiveXObject */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
284
        for (var i = 0; i < this.tail.length; i++) {
285
            var ex_xmlhttp = this.tail.shift();
286
            ex_xmlhttp.abort();
287
        }
288
        xmlhttp.onreadystatechange = function() {
289
            if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
290
                d = JSON.parse(xmlhttp.responseText);
291
                table.DrawSection(tableContainer,d.body);
292
                table.DrawSection(tableContainer,d.footer,"tfoot");
293
                table.LoadEndCalback(tableContainer);
294
                table.setVisability(tableContainer, true);
295
                if(typeof rq === "object"){
296
                    table.ColumnHover(tableContainer,rq.colNo);
297
                }
298
            }
299
        };
300
        xmlhttp.open("GET", this.RequestToUrl(rq), true);
301
        xmlhttp.send();
302
        this.tail.push(xmlhttp); //put in tail to may later abort any previous
303
    };
304
305
    this.setVisability = function(tableContainer,rq){
306
        var tbl = document.getElementById(tableContainer);
307
        if(rq===true){
308
            tbl.style.filter = "none";
309
            tbl.style.opacity = "1";
310
            tbl.style.cursor = "auto";
311
        } else if(rq===false){
312
            tbl.style.filter = "blur(1px)";
313
            tbl.style.opacity = "0.8";
314
            tbl.style.cursor = "wait";
315
        } else { console.log("table error in the rq value");}
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
316
    };
317
318
    this.getParent = function (obj,objType){
319
        while( obj && obj.tagName !== objType.toUpperCase() ){
320
            obj = obj.parentNode;
321
        } return obj;
322
    };
323
324
    this.init = function(tableId){
325
        this.SetTheTableColumnsHoverEffect(tableId);
326
    };
327
328
    this.iePrior = function(v) {var rv=false; if(/** global: navigator */navigator.appName==='Microsoft Internet Explorer') {var ua=navigator.userAgent; var re=new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})"); if(re.exec(ua)!==null) rv=parseFloat(RegExp.$1); rv=rv<v?true:false; } return rv;};
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
329
    this.loadJS = function(src){ var s = document.createElement('script'); s.src = src; document.getElementsByTagName('head')[0].appendChild(s);};
330
    this.loadCSS = function(src){ var s = document.createElement('link'); s.href = src; s.rel="stylesheet"; document.getElementsByTagName('head')[0].appendChild(s);};
331
332
    this.LoadEndCalback = function(tableId){if(tableId){}};
0 ignored issues
show
Comprehensibility Documentation Best Practice introduced by
This code block is empty. Consider removing it or adding a comment to explain.
Loading history...
333
    this.AppendRowCalback = function(tableId){if(tableId){}};
0 ignored issues
show
Comprehensibility Documentation Best Practice introduced by
This code block is empty. Consider removing it or adding a comment to explain.
Loading history...
334
};
335
336
/** Moves custom created filter to the Table's filter
337
 * @param {string} filterId
338
 * @param {string} tableId
339
 * @param {boolean} delay - needed in case the table is istill not executed */
340
function moveSelectorToTheTableFilter(filterId, tableId, delay){
341
    if(delay===true){
342
        setTimeout(function(){
343
            var filterDiv = document.getElementById(tableId).getElementsByTagName("div")[0];
344
            filterDiv.appendChild(document.getElementById(filterId));
345
        },500);
346
    } else {
347
        filterDiv = document.getElementById(tableId).getElementsByTagName("div")[0];
0 ignored issues
show
Bug introduced by
The variable filterDiv seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.filterDiv.
Loading history...
348
        filterDiv.appendChild(document.getElementById(filterId));
349
    }
350
}
351
function changeListCustomFilter(selectObj){
352
    var fId = selectObj.options[selectObj.selectedIndex].value;
353
    var varName = selectObj.getAttribute("name");
354
    var varPos = document.URL.indexOf(varName);
355
    if(varPos>0){
356
        var url = fId!=="{!--Empty--!}" ? document.URL.substring(0,varPos) : document.URL.substring(0,(varPos-1));
357
    } else {
358
        var separator = document.URL.indexOf("?")>0 ? "&" : "?";
359
        url = document.URL + (fId!=="{!--Empty--!}" ? separator : "");
360
    }
361
    var newUrl = url + (fId!=="{!--Empty--!}" ? (varName + "=" + fId) : "");
362
    location.assign(newUrl);
363
}
364
365
366
function tablesLoadData(){
367
    var tables = document.getElementsByTagName("table");
368
    var envPrior9 = table.iePrior(9);
369
    for (var i = 0; i < tables.length; i++) {
370
        var isProcessable = envPrior9 ?
371
                            typeof tables[i]["data-table"]!== 'undefined' :
372
                            tables[i].hasAttribute("data-table");
373
        if(isProcessable && tables[i].getAttribute("data-table") === "js"){
374
            table.LoadData(tables[i].id);
375
            table.SetTheTableColumnsHoverEffect(tables[i].id);
376
        }
377
    }
378
    if(table.iePrior(10)){
379
        table.loadJS("/add/helpers/table/add/json2.js");
380
    }
381
382
    /*if(table.iePrior(8)){ //can be used to add apropriate tables links modifications
383
        // loadCSS("/add/helpers/table/add/ie7-and-down.css");
384
    }*/
385
}
386
387
/*if(window.addEventListener){window.addEventListener('load',tablesLoadData,false);} else if(window.attachEvent){window.attachEvent('onload',tablesLoadData);}*/